/*************************************************
 * ThinkJot V2
 * Author: Jeswin P. (jeswin@process64.com)
 * Website: http://www.process64.com/thinkjot/
 * This code is distributed under the terms of the
 * Apache License, Version 2.0.
 * **********************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

using ThinkJot.Core.Utils;
using ThinkJot.Core.Blogs.Providers;

namespace ThinkJot.Core.Blogs.Providers.Xml
{
    public class DateTimeMapEntry : IComparable<DateTimeMapEntry>
    {
        private Guid entryId;
        public Guid EntryId
        {
            get { return entryId; }
            set { entryId = value; }
        }

        private int entryType = BlogEntry.NormalType;
        public int EntryType
        {
            get { return entryType; }
            set { entryType = value; }
        }

        private DateTime time;
        public DateTime Time
        {
            get { return time; }
            set { time = value; }
        }

        private string title;
        public string Title
        {
            get { return title; }
            set { title = value; }
        }

        private string author;
        public string Author
        {
            get { return author; }
            set { author = value; }
        }

        private bool publish;
        public bool Publish
        {
            get { return publish; }
            set { publish = value; }
        }

        #region IComparable<DateTimeMapEntry> Members

        public int CompareTo(DateTimeMapEntry other)
        {
            if (other.Time > Time) return -1;
            if (other.time < Time) return 1;
            return 0;
        }

        #endregion
    }

    public class DateTimeMap
    {
        private const string DateTimeMapFileName = "datetimemap.xml";

        List<DateTimeMapEntry> entries = new List<DateTimeMapEntry>();
        public List<DateTimeMapEntry> Entries
        {
            get { return entries; }
            set { entries = value; }
        }

        public void Add(DateTime dateTime, Guid entryId, string title, string author, bool publish, int entryType)
        {
            DateTimeMapEntry entry = new DateTimeMapEntry();
            entry.EntryId = entryId;
            entry.Time = dateTime;
            entry.Title = title;
            entry.Author = author;
            entry.Publish = publish;
            entry.EntryType = entryType;
            entries.Add(entry);
            entries.Sort();
        }

        public void Remove(Guid entryId)
        {
            entries.RemoveAll(
                delegate(DateTimeMapEntry entry)
                {
                    if (entry.EntryId == entryId) return true;
                    else return false;
                });
        }

        public List<Guid> GetEntryIdsLaterThan(DateTime dateTime)
        {
            List<Guid> results = new List<Guid>();
            foreach (DateTimeMapEntry entry in entries)
            {
                if (entry.Time > dateTime) results.Add(entry.EntryId);
            }
            return results;
        }

        public List<Guid> GetLastEntryIds(int count, bool showUnpublished, bool includeArticles)
        {
            List<Guid> results = new List<Guid>();
            int selectedCount = 0;
            for (int i = (entries.Count - 1); i >= 0; i--)
            {
                if ((showUnpublished || entries[i].Publish) &&
                    (includeArticles || entries[i].EntryType == BlogEntry.NormalType))
                {
                    results.Add(entries[i].EntryId);
                    selectedCount++;
                }
                if (selectedCount == count) break;
            }
            return results;
        }

        public List<DateTimeMapEntry> GetLastEntries(int count)
        {
            List<DateTimeMapEntry> results = new List<DateTimeMapEntry>();
            List<DateTimeMapEntry> lastEntries = entries.Count > count ?
                entries.GetRange(entries.Count - count, count) : entries;
            foreach (DateTimeMapEntry entry in lastEntries)
            {
                results.Add(entry);
            }
            return results;
        }

        public void Save(string blogName)
        {
            try
            {
                SerializationHelper serializer = new SerializationHelper();
                string dateTimeMapPath = Path.Combine(ProviderSettings.GetBlogContentFolder(blogName), DateTimeMapFileName);
                serializer.Serialize(this, dateTimeMapPath, ProviderSettings.NamespaceURI);
            }
            catch (Exception ex)
            {
                new XmlLogger().LogException(ex, blogName);
            }
        }

        public static DateTimeMap GetDateTimeMap(string blogName)
        {
            try
            {
                SerializationHelper serializer = new SerializationHelper();
                string dateTimeMapPath = Path.Combine(ProviderSettings.GetBlogContentFolder(blogName), DateTimeMapFileName);
                DateTimeMap dateTimeMap = (DateTimeMap)serializer.Deserialize(dateTimeMapPath, typeof(DateTimeMap), ProviderSettings.NamespaceURI);
                return dateTimeMap ?? new DateTimeMap();
            }
            catch (Exception ex)
            {
                new XmlLogger().LogException(ex, blogName);
                return new DateTimeMap();
            }
        }

        public void AddEntry(BlogEntry entry)
        {
            this.Add(entry.Time, entry.UniqueId, entry.Title, entry.Author, entry.Publish, entry.EntryType);           
        }

        public List<Guid> GetEntryIdsForMonth(int month, int year)
        {
            List<Guid> results = new List<Guid>();
            foreach (DateTimeMapEntry entry in entries)
            {
                if (entry.Time.Month == month && entry.Time.Year == year)
                    results.Add(entry.EntryId);
            }
            return results;
        }

        public List<Guid> GetAllEntryIds()
        {
            List<Guid> results = new List<Guid>();
            foreach (DateTimeMapEntry entry in entries)
            {
                results.Add(entry.EntryId);
            }
            return results;
        }
    }
}
